// Copyright (C) 2025, ZWSOFT Co., LTD.(Guangzhou)
// Licensed under the MIT License. See LICENSE in the project root for license information.

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System.Collections.ObjectModel;
using System.Windows.Media;
using TestClient.Domain;

namespace TestClient.ViewModel;

public partial class EntityIdChipInput : ObservableObject
{
    [ObservableProperty]
    private string value;

    public EntityIdChipInput(string value)
    {
        Value = value;
    }
}

public partial class HighlightTestViewModel : PageViewModelBase
{
    [ObservableProperty]
    private string entIdInput = "";

    [ObservableProperty]
    private string mode = "Curve";

    [ObservableProperty]
    private Color curColor = Color.FromRgb(0, 250, 0);

    public ObservableCollection<EntityIdChipInput> Inputs { get; set; } = [];
    public ObservableCollection<string> Modes { get; } = ["Curve", "Point", "Surface"];

    public IAsyncRelayCommand HighlightEntitiesCommand { get; }
    public IAsyncRelayCommand UnhighlightEntitiesCommand { get; }
    public IAsyncRelayCommand AddEntityBySelectCommand { get; }

    public HighlightTestViewModel(
        VFAdapterWrapper wrapper,
        ISnackNotifyService notifyService
        ) : base(wrapper, notifyService)
    {
        HighlightEntitiesCommand = CreateAsyncRpcCommand(OnHighlightEntities);
        UnhighlightEntitiesCommand = CreateAsyncRpcCommand(OnUnhighlightEntities);
        AddEntityBySelectCommand = CreateAsyncRpcCommand(OnSelectEntity);
    }

    [RelayCommand]
    private void AddEntityId()
    {
        AddEntityId(EntIdInput);
        EntIdInput = "";
    }

    [RelayCommand]
    private void RemoveEntityId(EntityIdChipInput value)
    {
        Inputs.Remove(value);
    }

    private async Task OnHighlightEntities()
    {
        EnsureConnected();

        var entities = Inputs.Select(x => x.Value).ToArray() ?? throw new Exception("Input is empty");
        switch (Mode)
        {
            case "Curve":
                await Task.Run(() =>
                {
                    Wrapper.ChangeLineColorWidthInsertMap(entities);
                });
                break;
            case "Point":
                var (r, g, b) = GetCurrentColor();
                await Task.Run(() =>
                {
                    Wrapper.ChangePointColorWidthInsertMap(entities, r, g, b);
                });
                break;
            case "Surface":
                (r, g, b) = GetCurrentColor();
                var rs = new int[entities.Length];
                var gs = new int[entities.Length];
                var bs = new int[entities.Length];
                Array.Fill(rs, r);
                Array.Fill(gs, g);
                Array.Fill(bs, b);
                await Task.Run(() =>
                {
                    Wrapper.ChangeSurfaceColorInsertMap(entities, rs, gs, bs);
                });
                break;
            default:
                break;
        }
    }

    private async Task OnUnhighlightEntities()
    {
        EnsureConnected();

        var entities = Inputs.Select(x => x.Value).ToArray() ?? throw new Exception("Input is empty");
        switch (Mode)
        {
            case "Curve":
                await Task.Run(() =>
                {
                    Wrapper.ChangeLineColorWidthFromMap(entities);
                });
                break;
            case "Point":
                await Task.Run(() =>
                {
                    Wrapper.ChangePointColorWidthFromMap(entities);
                });
                break;
            case "Surface":
                await Task.Run(() =>
                {
                    Wrapper.ChangeSurfaceColorFromMap(entities);
                });
                break;
            default:
                break;
        }
    }

    private async Task OnSelectEntity()
    {
        EnsureConnected();
        var entId = await ViewModelHelpers.SelectEnt(Wrapper, GetFilter());
        AddEntityId(entId);
    }

    private void AddEntityId(string? input)
    {
        input = input?.Trim();
        if (string.IsNullOrEmpty(input))
        {
            return;
        }
        if (Inputs.Any(x => x.Value == input))
        {
            return;
        }
        Inputs.Add(new EntityIdChipInput(input));
    }

    partial void OnModeChanged(string value)
    {
        Inputs.Clear();
    }

    private string GetFilter() => Mode;
    private (int, int, int) GetCurrentColor()
    {
        return (CurColor.R, CurColor.G, CurColor.B);
    }
}
